home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / Apache 1.0 / src / mod_cookies.c < prev    next >
Text File  |  1995-12-04  |  8KB  |  227 lines

  1.  
  2. /* ====================================================================
  3.  * Copyright (c) 1995 The Apache Group.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer. 
  11.  *
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in
  14.  *    the documentation and/or other materials provided with the
  15.  *    distribution.
  16.  *
  17.  * 3. All advertising materials mentioning features or use of this
  18.  *    software must display the following acknowledgment:
  19.  *    "This product includes software developed by the Apache Group
  20.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  21.  *
  22.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  23.  *    endorse or promote products derived from this software without
  24.  *    prior written permission.
  25.  *
  26.  * 5. Redistributions of any form whatsoever must retain the following
  27.  *    acknowledgment:
  28.  *    "This product includes software developed by the Apache Group
  29.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  30.  *
  31.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  32.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  34.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  35.  * IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  36.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  37.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  42.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  43.  * ====================================================================
  44.  *
  45.  * This software consists of voluntary contributions made by many
  46.  * individuals on behalf of the Apache Group and was originally based
  47.  * on public domain software written at the National Center for
  48.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  49.  * For more information on the Apache Group and the Apache HTTP server
  50.  * project, please see <http://www.apache.org/>.
  51.  *
  52.  */
  53.  
  54.  
  55. /* Netscape Cookies Fixup
  56.  *
  57.  * This is a module for Shambhala for handling Netscape cookies.
  58.  *
  59.  * On each request look for a Cookie: header.
  60.  * If we don't find one then send a Set-Cookie: header out with the request
  61.  * Future requests from the same client should keep the same Cookie line.
  62.  * Using the cookie log you can track the path a user takes through your
  63.  * files.
  64.  *
  65.  * The cookie and request are logged to a file.  Use the directive
  66.  * "CookieLog somefilename" in one of the config files to enable.
  67.  *
  68.  * Netscape 1.0+ is the only known browser to support cookies.  This
  69.  * code is lazy and doesn't bother creating cookies for other browsers.
  70.  *
  71.  * Mark Cox, mark@telescope.org, 6 July 95
  72.  */
  73.  
  74. #include "httpd.h"
  75. #include "http_config.h"
  76. #include <sys/time.h>
  77.  
  78. module cookies_module;
  79.  
  80. /* Now we have to generate something that is going to be
  81.  * pretty unique.  We can base it on the pid, time, hostip */
  82.  
  83. void make_cookie(request_rec *r)
  84. {
  85.     struct timeval tv;
  86.     char new_cookie[100];    /* blurgh */
  87.     char *dot;
  88.     char *rname = pstrdup(r->pool,r->connection->remote_name);
  89.     struct timezone tz = { 0 , 0 };
  90.  
  91.     if ((dot = strchr(rname,'.'))) *dot='\0';    /* First bit of hostname */
  92.     gettimeofday(&tv, &tz);
  93.     sprintf(new_cookie,"s=%s%d%ld%d; path=/",
  94.         rname,
  95.         (int)getpid(),  
  96.         (long)tv.tv_sec, (int)tv.tv_usec/1000 );
  97.  
  98.     table_set(r->headers_out,"Set-Cookie",new_cookie);
  99.     return;
  100. }
  101.  
  102. int spot_cookie(request_rec *r)
  103. {
  104.     char *cookie, *agent;
  105.  
  106.     if (!(agent = table_get(r->headers_in,"User-Agent")))
  107.         return DECLINED;              /* No user-agent = No cookie */
  108.     if (strncmp(agent,"Mozilla",7))   /* Don't bother creating a cookie */
  109.         return DECLINED;              /* unless browser is Netscape fudge */
  110.     if ((cookie = table_get (r->headers_in, "Cookie")))
  111.         return DECLINED;              /* Theres already a cookie, no new one */
  112.     make_cookie(r);
  113.     return OK;                        /* We set our cookie */
  114. }
  115.  
  116. static int cookie_flags = ( O_WRONLY | O_APPEND | O_CREAT );
  117. static mode_t cookie_mode = ( S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );
  118.  
  119. typedef struct {
  120.     char *fname;
  121.     int log_fd;
  122. } cookie_log_state;
  123.  
  124. void *make_cookie_log_state (pool *p, server_rec *s)
  125. {
  126.     cookie_log_state *cls =
  127.       (cookie_log_state *)palloc (p, sizeof (cookie_log_state));
  128.  
  129.     cls->fname = "";
  130.     cls->log_fd = -1;
  131.  
  132.     return (void *)cls;
  133. }
  134.  
  135. char *set_cookie_log (cmd_parms *parms, void *dummy, char *arg)
  136. {
  137.     cookie_log_state *cls = get_module_config (parms->server->module_config,
  138.                            &cookies_module);
  139.     cls->fname = arg;
  140.     return NULL;
  141. }
  142.  
  143. command_rec cookie_log_cmds[] = {
  144. { "CookieLog", set_cookie_log, NULL, RSRC_CONF, TAKE1,
  145.     "the filename of the cookie log" },
  146. { NULL }
  147. };
  148.  
  149. void open_cookie_log (server_rec *s, pool *p)
  150. {
  151.     cookie_log_state *cls = get_module_config (s->module_config,
  152.                            &cookies_module);
  153.     char *fname = server_root_relative (p, cls->fname);
  154.  
  155.     if (cls->log_fd > 0) return; 
  156.     cls->log_fd = popenf(p, fname, cookie_flags, cookie_mode);
  157. }
  158.  
  159. void init_cookie_log (server_rec *s, pool *p)
  160. {
  161.     for (; s; s = s->next) open_cookie_log (s, p);
  162. }
  163.  
  164. int cookie_log_transaction(request_rec *orig)
  165. {
  166.     cookie_log_state *cls = get_module_config (orig->server->module_config,
  167.                            &cookies_module);
  168.     char str[HUGE_STRING_LEN];
  169.     long timz;
  170.     struct tm *t;
  171.     char tstr[MAX_STRING_LEN],sign;
  172.     request_rec *r;
  173.     char *cookie;
  174.  
  175.     for (r = orig; r->next; r = r->next)
  176.         continue;
  177.     if ((cls->log_fd)<0)    /* Don't log cookies */
  178.     return DECLINED;
  179.  
  180.     if (!(cookie = table_get (r->headers_in, "Cookie")))
  181.         return DECLINED;    /* Theres no cookie, don't bother logging */
  182.     if (strncmp(cookie,"s=",2)) /* Only log cookies we generated! */
  183.         return DECLINED;
  184.     t = get_gmtoff(&timz);
  185.     sign = (timz < 0 ? '-' : '+');
  186.     if(timz < 0) 
  187.         timz = -timz;
  188.  
  189.     strftime(tstr,MAX_STRING_LEN,"%d/%b/%Y:%H:%M:%S",t);
  190.  
  191.     sprintf(str,"%s \"%s\" [%s %c%02ld%02ld] ",
  192.         cookie+2,        /* Ignore s= */
  193.         orig->the_request,
  194.             tstr,
  195.             sign,
  196.             timz/3600,
  197.             timz%3600);
  198.     
  199.     if (r->status != -1)
  200.         sprintf(str,"%s%d\n",str,r->status);
  201.     else
  202.         strcat(str,"-\n");
  203.  
  204.     write(cls->log_fd, str, strlen(str));
  205.  
  206.     return OK;
  207. }
  208.  
  209.  
  210. module cookies_module = {
  211.    STANDARD_MODULE_STUFF,
  212.    init_cookie_log,                /* initializer */
  213.    NULL,                        /* dir config creater */
  214.    NULL,                        /* dir merger --- default is to override */
  215.    make_cookie_log_state,        /* server config */
  216.    NULL,                        /* merge server configs */
  217.    cookie_log_cmds,                /* command table */
  218.    NULL,                        /* handlers */
  219.    NULL,                        /* filename translation */
  220.    NULL,                        /* check_user_id */
  221.    NULL,                        /* check auth */
  222.    NULL,                        /* check access */
  223.    NULL,                        /* type_checker */
  224.    spot_cookie,                    /* fixups */
  225.    cookie_log_transaction,        /* logger */
  226. };
  227.